package com.bitejiuyeke.job_publish.controller;

import com.bitejiuyeke.job_publish.common.AppResult;
import com.bitejiuyeke.job_publish.common.ResultCode;
import com.bitejiuyeke.job_publish.config.RabbitMQConfig;
import com.bitejiuyeke.job_publish.controller.params.VerificationCodeDTO;
import com.bitejiuyeke.job_publish.enums.VerifyCodeTargetEnum;
import com.bitejiuyeke.job_publish.enums.VerifyCodeTypeEnum;
import com.bitejiuyeke.job_publish.exception.ApplicationException;
import com.bitejiuyeke.job_publish.model.User;
import com.bitejiuyeke.job_publish.model.VerificationCode;
import com.bitejiuyeke.job_publish.mq.model.VerificationCodeMQ;
import com.bitejiuyeke.job_publish.service.IUserService;
import com.bitejiuyeke.job_publish.service.IVerificationCodeService;
import com.bitejiuyeke.job_publish.utils.RegexUtils;
import com.bitejiuyeke.job_publish.utils.VerificationCodeUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 比特就业课
 */
// API描述
@Tag(name = "验证码操作相关接口")
// 日志
@Slf4j
// Controller注解，返回的对象用JSON形式表示
@RestController
// 路径映射
@RequestMapping("/verify")
public class VerificationCodeController {

    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private IVerificationCodeService service;
    @Resource
    private IUserService userService;

    @Operation(summary = "发送短信验证码")
    @PostMapping("/send")
    public AppResult send(@Validated @RequestBody VerificationCodeDTO param) {
        // 验证类型
        VerifyCodeTargetEnum targetEnum = null;
        // 1. 用户信息
        User user = null;
        // 是否手机号
        if (RegexUtils.checkMobile(param.getTargetNum())) {
            targetEnum = VerifyCodeTargetEnum.PHONE;
            user = userService.selectByPhoneNum(param.getTargetNum());
        }
        // 是否电子邮件
        if (RegexUtils.checkMail(param.getTargetNum())) {
            targetEnum = VerifyCodeTargetEnum.EMAIL;
            user = userService.selectByEmail(param.getTargetNum());
        }
        // 格式校验不通过
        if (targetEnum == null) {
            throw new ApplicationException(AppResult.failed("手机号码或邮箱地址格式不正确."));
        }

        // 2. 根据类型校验操作是否合法
        if (param.getType() == VerifyCodeTypeEnum.REGISTER.getCode()) {
            // 注册操作时电话号码已存在
            if (user != null) {
                log.info(ResultCode.FAILED_TARGET_NUM_EXISTS.toString());
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TARGET_NUM_EXISTS));
            }
        } else {
            // 其他操作时电话号码不存在
            if (user == null) {
                log.info(ResultCode.FAILED_TARGET_NUM_NOT_EXISTS.toString());
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TARGET_NUM_NOT_EXISTS));
            }
        }
        // 3. 生成验证码并入库
        String code = VerificationCodeUtils.generateVerificationCode();
        VerificationCode vc = new VerificationCode();
        vc.setPhoneNum(param.getTargetNum()); // 电话号
        vc.setType(param.getType().byteValue()); // 类型
        vc.setCode(code); // 验证码
        // 4. 写入数据库
        service.create(vc);
        // 5. 发送到消息队列
        VerificationCodeMQ vcmq = new VerificationCodeMQ();
        vcmq.setTargetNum(param.getTargetNum());
        vcmq.setCode(code);
        vcmq.setType(targetEnum.getCode());
        // 发送消息
        rabbitTemplate.convertAndSend(RabbitMQConfig.BITE_JOB_EXCHANGE_NAME,
                RabbitMQConfig.BITE_JOB_V_CODE_ROUTING_KEY, vcmq);
        // 6. 返回结果
        return AppResult.success();
    }

}
